package com.minsf.rpc.server.tcp;

import com.minsf.rpc.RpcApplication;
import com.minsf.rpc.model.RpcRequest;
import com.minsf.rpc.model.RpcResponse;
import com.minsf.rpc.protocol.*;
import com.minsf.rpc.registry.EtcdRegistry;
import com.minsf.rpc.registry.LocalRegistry;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * @Description
 * @Author minify
 * @Date 2024/3/30 13:42
 * @Project sf-rpc
 */
public class TcpServerHandler implements Handler<NetSocket> {

    @Override
    public void handle(NetSocket netSocket) {
        TcpBufferHandlerWrapper tcpBufferHandlerWrapper = new TcpBufferHandlerWrapper(buffer -> {
            // 接受请求 解码
            ProtocolMessage<RpcRequest> protocolMessage;

            try {
                protocolMessage = (ProtocolMessage<RpcRequest>) ProtocolMessageDecoder.decoder(buffer);
            } catch (Exception e){
                throw new RuntimeException("协议消息解码错误");
            }

            // 消息体
            RpcRequest data = protocolMessage.getData();
            // 构造响应
            RpcResponse response = new RpcResponse();
            try {
                String serviceName = data.getServiceName();
                Class<?> implClass = LocalRegistry.get(serviceName);

                Method method = implClass.getMethod(data.getMethodName(), data.getParameterTypes());

                Object invoke = method.invoke(implClass.newInstance(), data.getArgs());

                // 封装响应结果
                response.setData(invoke);
                response.setDataType(method.getReturnType());
                response.setMessage("ok");

            } catch (Exception e) {
                response.setMessage(e.getMessage());
                response.setException(e);
            }

            ProtocolMessage.Header header = protocolMessage.getHeader();
            header.setType((byte) ProtocolMessageTypeEnum.RESPONSE.getKey());
            header.setStatus((byte) ProtocolMessageStatusEnum.OK.getValue());

            ProtocolMessage<RpcResponse> responseProtocolMessage = new ProtocolMessage<>();
            responseProtocolMessage.setHeader(header);
            responseProtocolMessage.setData(response);
            try {
                Buffer encode = ProtocolMessageEncoder.encode(responseProtocolMessage);
                // 响应
                netSocket.write(encode);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });

        // 处理连接
        netSocket.handler(tcpBufferHandlerWrapper);
    }
}
